//
//  HDAppPayManager.m
//  HaiDiProject
//
//  Created by Dxc_iOS on 2018/3/9.
//  Copyright © 2018年 XinMiao. All rights reserved.
//

#import "IPAManager.h"
#import <StoreKit/StoreKit.h>
#import "MBProgressHUD.h"

#define kKeyWindow [UIApplication sharedApplication].keyWindow
@interface IPAManager()<SKPaymentTransactionObserver,SKProductsRequestDelegate>{
    NSString           *_purchID;
    IAPCompletionHandle _handle;
}
@property (nonatomic, strong) MBProgressHUD *hud;
@property (nonatomic, copy)  NSString *transactionReceiptString;//交易凭证
@property (nonatomic, copy) NSString *moneyID;
@end
@implementation IPAManager

#pragma mark - ♻️life cycle

+ (instancetype)shareSIAPManager{
    
    static IPAManager *IAPManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,^{
        IAPManager = [[IPAManager alloc] init];
    });
    return IAPManager;
}

- (instancetype)init{
    self = [super init];
    if (self) {
        // 购买监听写在程序入口,程序挂起时移除监听,这样如果有未完成的订单将会自动执行并回调 paymentQueue:updatedTransactions:方法
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    }
    return self;
}

- (void)dealloc{
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}


#pragma mark - 🚪public
- (void)startPurchWithID:(NSString *)purchID moneyID:(NSString *)moneyID completeHandle:(IAPCompletionHandle)handle{
    if (purchID) {
        if ([SKPaymentQueue canMakePayments]) {
            // Hud
            MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:kKeyWindow animated:YES];
            hud.label.text = @"正在购买,请不要离开...";
            hud.dimBackground = YES;
            self.hud = hud;
            // 开始购买服务
            _purchID = purchID;
            _handle = handle;
            _moneyID = moneyID;
           // 1.拿到所有可卖商品的ID数组
            NSSet *nsset = [NSSet setWithArray:@[purchID]];
             // 2.向苹果发送请求，请求所有可买的商品
            SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
            request.delegate = self;
            [request start];
        }else{
            [self handleActionWithType:IAPPurchNotArrow data:nil];
        }
    }
}


#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
    NSArray *product = response.products;
    if([product count] <= 0){
#if DEBUG
        NSLog(@"--------------没有商品------------------");
         [MBProgressHUD hideAllHUDsForView:kKeyWindow animated:YES];
#endif
        return;
    }
    
    SKProduct *p = nil;
    for(SKProduct *pro in product){
        if([pro.productIdentifier isEqualToString:_purchID]){
            p = pro;
            break;
        }
    }
    
#if DEBUG
    NSLog(@"responseInfo=\n%@",response);
    NSLog(@"productID:%@", response.invalidProductIdentifiers);
    
    NSLog(@"产品付费数量=\n%lu",(unsigned long)[product count]);
    NSLog(@"描述信息=\n%@",[p description]);
    NSLog(@"产品标题=\n%@",[p localizedTitle]);
    NSLog(@"产品描述信息=\n%@",[p localizedDescription]);
    NSLog(@"产品价格=\n%@",[p price]);
    NSLog(@"产品ID:ProductId=\n%@",[p productIdentifier]);
    NSLog(@"发送购买请求");
#endif
/**
 发送购买请求
 */
//    创建票据
    SKPayment *payment = [SKPayment paymentWithProduct:p];
//    将票据加入到交易队列
    [[SKPaymentQueue defaultQueue] addPayment:payment];
  
}

/**
 发送购买请求失败
 */
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
#if DEBUG
    NSLog(@"------------------ 发送购买请求失败-----------------:%@", error);
#endif
    [MBProgressHUD hideHUDForView:kKeyWindow animated:YES];
    
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:kKeyWindow animated:YES];
    hud.label.text = @"请求购买失败";
    hud.mode = MBProgressHUDModeText;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [MBProgressHUD hideHUDForView:kKeyWindow animated:YES];
    });
}
/**
 发送购买请求完成
 */
- (void)requestDidFinish:(SKRequest *)request{
#if DEBUG
       NSLog(@"购买请求完成");
    NSLog(@"------------反馈信息结束-----------------");
#endif
}
/**
 实现观察者监听付钱的代理方法,只要交易发生变化就会走下面的方法
 */
#pragma mark - SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
    /*
     SKPaymentTransactionStatePurchasing,    正在购买
     SKPaymentTransactionStatePurchased,     已经购买
     SKPaymentTransactionStateFailed,        购买失败
     SKPaymentTransactionStateRestored,      回复购买中
     SKPaymentTransactionStateDeferred       交易还在队列里面，但最终状态还没有决定
     */
    
    for (SKPaymentTransaction *tran in transactions) {
        switch (tran.transactionState) {
            case SKPaymentTransactionStatePurchased:{
#if DEBUG
                NSLog(@"购买成功");
#endif
                // 购买成功后告诉交易队列，把这个成功的交易移除掉，然后再处理
                [queue finishTransaction:tran];
                //去验证是否真正的支付成功了（苹果服务器验证,和自己的服务器验证）
                // 交易验证
                [self verifyPurchaseWithPaymentTransaction:tran isTestServer:NO];
                [self completeTransaction:tran];
            } break;
            case SKPaymentTransactionStatePurchasing:{
#if DEBUG
                NSLog(@"正在购买");
                NSLog(@"商品添加进列表");
#endif
            }break;
            case SKPaymentTransactionStateRestored:{
                // 消耗型不支持恢复购买
#if DEBUG
                NSLog(@"恢复购买,也叫做已经购买过商品");
#endif
                // 恢复购买中也要把这个交易移除掉
                [queue finishTransaction:tran];
            }break;
            case SKPaymentTransactionStateFailed:{
#if DEBUG
                NSLog(@"购买失败");
#endif
                // 购买失败也要把这个交易移除掉
                [self failedTransaction:tran];
            }break;
            case SKPaymentTransactionStateDeferred:{
 #if DEBUG
                NSLog(@"交易还在队列里面，但最终状态还没有决定");
#endif
            }break;
            default:
                break;
        }
    }
}



/**
// 交易成功后 处理交易结果
 */
- (void)completeTransaction:(SKPaymentTransaction *)transaction{
    // Your application should implement these two methods.
     NSLog(@"交易结束，并向自己的服务器验证");
    
    NSString * productIdentifier = transaction.payment.productIdentifier;
    NSLog(@"productIdentifier Product id：%@", productIdentifier);
    NSString *transactionReceiptString;
    //系统IOS7.0以上获取支付验证凭证的方式应该改变，切验证返回的数据结构也不一样了。
    NSString *version = [UIDevice currentDevice].systemVersion;
    if([version intValue] >= 7.0){
        // 验证凭据，获取到苹果返回的交易凭据
        // appStoreReceiptURL iOS7.0增加的，购买交易完成后，会将凭据存放在该地址
        NSURLRequest * appstoreRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle]appStoreReceiptURL]];
        NSError *error = nil;
        NSData * receiptData = [NSURLConnection sendSynchronousRequest:appstoreRequest returningResponse:nil error:&error];
        transactionReceiptString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    
    }else{
        
        NSData * receiptData = transaction.transactionReceipt;
        //  transactionReceiptString = [receiptData base64EncodedString];
        transactionReceiptString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    }
      DDLogVerbose(@"transactionReceiptString = \n%@",transactionReceiptString);
   
        if ([productIdentifier length] > 0) {
          self.hud.label.text = @"正在验证,请勿离开...";
            // 向自己的服务器验证购买凭证
//
//            [MineAskManger mineGetHaiBeiIPAWithUid:[LoginTool uid] hashid:[LoginTool hashid] moneyid:_moneyID  apple_receipt:transactionReceiptString withSuccessBlock:^(id json) {
//                // 往后台验证
//                DDLogVerbose(@"后台验证返回JSON=\n%@",json);
//                NSLog(@"后台验证成功");
//                [self handleActionWithType:IAPPurchSuccess data:nil];
//                [MBProgressHUD hideAllHUDsForView:kKeyWindow animated:YES];
//                //通知刷新嗨贝壳
//                  [[NSNotificationCenter defaultCenter]postNotificationName:@"HaiBeiRefresh" object:nil];
//
//            }];
        
        }
    

    
}
/**
 交易失败 （1.手动取消  2.其他错误）
 */
- (void)failedTransaction:(SKPaymentTransaction *)transaction{
    if (transaction.error.code != SKErrorPaymentCancelled) {
        [self handleActionWithType:IAPPurchFailed data:nil];
         self.hud.label.text = @"交易失败...";
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 *
                                                                  NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
           [MBProgressHUD hideAllHUDsForView:kKeyWindow animated:YES];
        });

       
    
    }else{
        [self handleActionWithType:IAPPurchCancle data:nil];
         self.hud.label.text = @"交易取消...";
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 *
                                                                  NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            [MBProgressHUD hideAllHUDsForView:kKeyWindow animated:YES];
        });
        
    }
//    移除掉交易队列
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

 /**
  交易验证（向苹果服务器验证）
  */
- (void)verifyPurchaseWithPaymentTransaction:(SKPaymentTransaction *)transaction isTestServer:(BOOL)flag{
  //从沙盒中获取交易凭证并且拼接成请求体数据
    // appStoreReceiptURL iOS7.0增加的，购买交易完成后，会将凭据存放在该地址
    NSURL *recepitURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receipt = [NSData dataWithContentsOfURL:recepitURL];
   
    if(!receipt){
        // 交易凭证为空验证失败
         NSLog(@"交易凭证为空验证失败");
        [self handleActionWithType:IAPPurchVerFailed data:nil];
        return;
    }
    // 购买成功将交易凭证发送给服务端进行再次校验
    [self handleActionWithType:IAPPurchSuccess data:receipt];
    
    NSError *error;
    NSDictionary *requestContents = @{
                                      @"receipt-data": [receipt base64EncodedStringWithOptions:0]
                                      };
    
    NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0  error:&error];
    
    if (!requestData) { // 交易凭证为空验证失败
         NSLog(@"交易凭证为空验证失败");
        [self handleActionWithType:IAPPurchVerFailed data:nil];
        return;
    }
    
    //In the test environment, use https://sandbox.itunes.apple.com/verifyReceipt
    //In the real environment, use https://buy.itunes.apple.com/verifyReceipt
    
    NSString *serverString = @"https://buy.itunes.apple.com/verifyReceipt";
    if (flag) {
        serverString = @"https://sandbox.itunes.apple.com/verifyReceipt";
    }
    NSURL *storeURL = [NSURL URLWithString:serverString];
    NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
    [storeRequest setHTTPMethod:@"POST"];
    [storeRequest setHTTPBody:requestData];
    
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
                   completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
               if (connectionError) {
                   // 无法连接服务器,购买校验失败
                   [self handleActionWithType:IAPPurchVerFailed data:nil];
               } else {
                   NSError *error;
                   NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
                   if (!jsonResponse) {
                       // 苹果服务器校验数据返回为空校验失败
                       [self handleActionWithType:IAPPurchVerFailed data:nil];
                   }
                   
                   // 先验证正式服务器,如果正式服务器返回21007再去苹果测试服务器验证,沙盒测试环境苹果用的是测试服务器
                   NSString *status = [NSString stringWithFormat:@"%@",jsonResponse[@"status"]];
                   if (status && [status isEqualToString:@"21007"]) {
                       [self verifyPurchaseWithPaymentTransaction:transaction isTestServer:YES];
                   }else if(status && [status isEqualToString:@"0"]){
                       [self handleActionWithType:IAPPurchVerSuccess data:nil];
                   }
#if DEBUG
                    NSLog(@"----验证结果 %@",jsonResponse);
#endif
                    }
                           }];
    
    
    // 验证成功与否都注销交易,否则会出现虚假凭证信息一直验证不通过,每次进程序都得输入苹果账号
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

#pragma mark - 🔒private   状态
- (void)handleActionWithType:(IAPPurchType)type data:(NSData *)data{
#if DEBUG
    switch (type) {
        case IAPPurchSuccess:
            NSLog(@"购买成功");
            break;
        case IAPPurchFailed:
            NSLog(@"购买失败");
            break;
        case IAPPurchCancle:
            NSLog(@"用户取消购买");
            break;
        case IAPPurchVerFailed:
            NSLog(@"订单校验失败");
            break;
        case IAPPurchVerSuccess:
            NSLog(@"订单校验成功");
            break;
        case IAPPurchNotArrow:
            NSLog(@"不允许程序内付费");
            break;
        default:
            break;
    }
#endif
    if(_handle){
        _handle(type,data);
    }
}


@end
